// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************

// Stage: @prod
// Group: @system_console

import * as TIMEOUTS from '../../../fixtures/timeouts';

describe('Customization', () => {
    let origConfig;

    before(() => {
        // # Login as sysadmin
        cy.apiLogin('sysadmin');

        // Get config
        cy.apiGetConfig().then((response) => {
            origConfig = response.body;
        });

        // # Visit customization system console page
        cy.visit('/admin_console/site_config/customization');
        cy.get('.admin-console__header').should('be.visible').and('have.text', 'Customization');
    });

    it('SC20336 - Can change Custom Brand Image setting', () => {
        // # Make sure necessary field is false
        cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: false}});
        cy.reload();

        // # Set Enable Custom Branding to true to be able to upload custom brand image
        cy.get('[id="TeamSettings.EnableCustomBrandtrue"]').check();

        cy.findByTestId('CustomBrandImage').should('be.visible').within(() => {
            // * Verify that setting is visible and matches text content
            cy.get('label').should('be.visible').and('have.text', 'Custom Brand Image:');

            // * Verify that help setting is visible and matches text content
            const contents = 'Customize your user experience by adding a custom image to your login screen. Recommended maximum image size is less than 2 MB.';
            cy.get('.help-text').should('be.visible').and('have.text', contents);

            // # upload the image
            cy.fileUpload('input');
        });

        // # Save setting
        saveSetting();

        // # Verify that after page reload image exist
        cy.reload();
        cy.findByTestId('CustomBrandImage').should('be.visible').within(() => {
            cy.get('img').should('have.attr', 'src').and('include', '/api/v4/brand/image?t=');
        });
    });

    it('SC20335 - Can change Site Name setting', () => {
        // * Verify site name's setting name for is visible and matches the text
        cy.findByTestId('TeamSettings.SiteNamelabel').scrollIntoView().should('be.visible').and('have.text', 'Site Name:');

        // * Verify the site name input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('TeamSettings.SiteNameinput').should('have.value', origConfig.TeamSettings.SiteName);

        // * Verify the site name's help text is visible and matches the text
        cy.findByTestId('TeamSettings.SiteNamehelp-text').should('be.visible').and('have.text', 'Name of service shown in login screens and UI. When not specified, it defaults to "Mattermost".');

        // # Generate and enter a random site name
        const siteName = 'New site name';
        cy.findByTestId('TeamSettings.SiteNameinput').clear().type(siteName);

        // # Save setting
        saveSetting();

        // Get config again
        cy.apiGetConfig().then((response) => {
            const config = response.body;

            // * Verify the site name is saved, directly via REST API
            expect(config.TeamSettings.SiteName).to.eq(siteName);
        });
    });

    it('SC20332 - Can change Site Description setting', () => {
        // * Verify site description label is visible and matches the text
        cy.findByTestId('TeamSettings.CustomDescriptionTextlabel').should('be.visible').and('have.text', 'Site Description: ');

        // * Verify the site description input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('TeamSettings.CustomDescriptionTextinput').should('have.value', origConfig.TeamSettings.CustomDescriptionText);

        // * Verify the site description help text is visible and matches the text
        cy.findByTestId('TeamSettings.CustomDescriptionTexthelp-text').find('span').should('be.visible').and('have.text', 'Description of service shown in login screens and UI. When not specified, "All team communication in one place, searchable and accessible anywhere" is displayed.');

        // # Generate and enter a random site description
        const siteDescription = 'New site description';
        cy.findByTestId('TeamSettings.CustomDescriptionTextinput').clear().type(siteDescription);

        // # Save setting
        saveSetting();

        // Get config again
        cy.apiGetConfig().then((response) => {
            // * Verify the site description is saved, directly via REST API
            expect(response.body.TeamSettings.CustomDescriptionText).to.eq(siteDescription);
        });
    });

    it('SC20342 - Can change Custom Brand Text setting', () => {
        // * Verify custom brand text label is visible and matches the text
        cy.findByTestId('TeamSettings.CustomBrandTextlabel').scrollIntoView().should('be.visible').and('have.text', 'Custom Brand Text:');

        // * Verify the custom brand input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('TeamSettings.CustomBrandTextinput').should('have.value', origConfig.TeamSettings.CustomBrandText);

        // * Verify the custom brand help text is visible and matches the text
        cy.findByTestId('TeamSettings.CustomBrandTexthelp-text').find('span').should('be.visible').and('have.text', 'Text that will appear below your custom brand image on your login screen. Supports Markdown-formatted text. Maximum 500 characters allowed.');

        //Enable custom branding
        cy.findByTestId('TeamSettings.EnableCustomBrandtrue').check({force: true});

        // # Enter a custom brand text
        const customBrandText = 'Random brand text';
        cy.findByTestId('TeamSettings.CustomBrandTextinput').clear().type(customBrandText);

        // # Save setting
        saveSetting();

        // Get config again
        cy.apiGetConfig().then((response) => {
            // * Verify the custom brand text is saved, directly via REST API
            expect(response.body.TeamSettings.CustomBrandText).to.eq(customBrandText);
        });
    });

    it('SC20331 - Can change Report a Problem Link setting', () => {
        // * Verify Report a Problem link label is visible and matches the text
        cy.findByTestId('SupportSettings.ReportAProblemLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Report a Problem Link:');

        // * Verify Report a Problem link input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('SupportSettings.ReportAProblemLinkinput').should('have.value', origConfig.SupportSettings.ReportAProblemLink);

        // * Verify Report a Problem link help text is visible and matches the text
        cy.findByTestId('SupportSettings.ReportAProblemLinkhelp-text').find('span').should('be.visible').and('have.text', 'The URL for the Report a Problem link in the Main Menu. If this field is empty, the link is removed from the Main Menu.');

        // # Enter a problem link
        const reportAProblemLink = 'https://about.mattermost.com/default-report-a-problem/test';
        cy.findByTestId('SupportSettings.ReportAProblemLinkinput').clear().type(reportAProblemLink);

        // # Save setting
        saveSetting();

        // Get config again
        cy.apiGetConfig().then((response) => {
            // * Verify the Report a Problem link is saved, directly via REST API
            expect(response.body.SupportSettings.ReportAProblemLink).to.eq(reportAProblemLink);
        });
    });

    it('SC20330 - Can change Privacy Policy Link setting', () => {
        // * Verify that setting is visible and matches text content
        cy.findByTestId('SupportSettings.PrivacyPolicyLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Privacy Policy Link:');

        // * Verify that help setting is visible and matches text content
        const content = 'The URL for the Privacy link on the login and sign-up pages. If this field is empty, the Privacy link is hidden from users.';
        cy.findByTestId('SupportSettings.PrivacyPolicyLinkhelp-text').scrollIntoView().find('span').should('be.visible').and('have.text', content);

        // * Verify the input box visible and has default value
        cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').scrollIntoView().should('have.value', origConfig.SupportSettings.PrivacyPolicyLink).and('be.visible');

        // # Fill input field with value
        const stringToSave = 'https://some.com';
        cy.findByTestId('SupportSettings.PrivacyPolicyLinkinput').clear().type(stringToSave);

        // # Save setting
        saveSetting();

        // * Verify that the value is save, directly via REST API
        cy.apiGetConfig().then((response) => {
            expect(response.body.SupportSettings.PrivacyPolicyLink).to.equal(stringToSave);
        });
    });

    it('SC20337 Can change Support Email setting', () => {
        // # Scroll Support Email section into view and verify that it's visible
        cy.findByTestId('SupportSettings.SupportEmail').scrollIntoView().should('be.visible');

        // * Verify that setting label is visible and matches text content
        cy.findByTestId('SupportSettings.SupportEmaillabel').should('be.visible').and('have.text', 'Support Email:');

        // * Verify the Support Email input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('SupportSettings.SupportEmailinput').should('have.value', origConfig.SupportSettings.SupportEmail);

        // * Verify that the help text is visible and matches text content
        cy.findByTestId('SupportSettings.SupportEmailhelp-text').find('span').should('be.visible').and('have.text', 'Email address displayed on email notifications and during tutorial for end users to ask support questions.');

        const newEmail = 'support@example.com';

        // * Verify that set value is visible and matches text
        cy.findByTestId('SupportSettings.SupportEmail').find('input').clear().type(newEmail).should('have.value', newEmail);

        // # Save setting
        saveSetting();

        // * Verify that the config is correctly saved in the server
        cy.apiGetConfig().then((response) => {
            expect(response.body.SupportSettings.SupportEmail).to.equal(newEmail);
        });
    });

    it('SC20338 Can change Android App Download Link setting', () => {
        // # Scroll Android App Download Link section into view and verify that it's visible
        cy.findByTestId('NativeAppSettings.AndroidAppDownloadLink').scrollIntoView().should('be.visible');

        // * Verify that Android App Download Link label is visible and matches text content
        cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinklabel').should('be.visible').and('have.text', 'Android App Download Link:');

        // * Verify the Android App Download Link input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinkinput').should('have.value', origConfig.NativeAppSettings.AndroidAppDownloadLink);

        // * Verify that the help text is visible and matches text content
        cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinkhelp-text').find('span').should('be.visible').and('have.text', 'Add a link to download the Android app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.');

        const newAndroidAppDownloadLink = 'https://example.com/android-app/';

        // * Verify that set value is visible and matches text
        cy.findByTestId('NativeAppSettings.AndroidAppDownloadLinkinput').clear().type(newAndroidAppDownloadLink).should('have.value', newAndroidAppDownloadLink);

        // # Save setting
        saveSetting();

        // * Verify that the config is correctly saved in the server
        cy.apiGetConfig().then((response) => {
            expect(response.body.NativeAppSettings.AndroidAppDownloadLink).to.equal(newAndroidAppDownloadLink);
        });
    });

    it('SC20340 Can change iOS App Download Link setting', () => {
        // # Scroll iOS App Download Link section into view and verify that it's visible
        cy.findByTestId('NativeAppSettings.IosAppDownloadLink').scrollIntoView().should('be.visible');

        // * Verify that iOS App Download Link label is visible and matches text content
        cy.findByTestId('NativeAppSettings.IosAppDownloadLinklabel').should('be.visible').and('have.text', 'iOS App Download Link:');

        // * Verify the iOS App Download Link input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('NativeAppSettings.IosAppDownloadLinkinput').should('have.value', origConfig.NativeAppSettings.IosAppDownloadLink);

        // * Verify that the help text is visible and matches text content
        cy.findByTestId('NativeAppSettings.IosAppDownloadLinkhelp-text').find('span').should('be.visible').and('have.text', 'Add a link to download the iOS app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.');

        const newIosAppDownloadLink = 'https://example.com/iOS-app/';

        // * Verify that set value is visible and matches text
        cy.findByTestId('NativeAppSettings.IosAppDownloadLinkinput').clear().type(newIosAppDownloadLink).should('have.value', newIosAppDownloadLink);

        // # Save setting
        saveSetting();

        // * Verify that the config is correctly saved in the server
        cy.apiGetConfig().then((response) => {
            expect(response.body.NativeAppSettings.IosAppDownloadLink).to.equal(newIosAppDownloadLink);
        });
    });

    it('SC20333 - Can change Mattermost Apps Download Page Link setting', () => {
        // * Verify Mattermost Apps Download Page Link's setting name is visible and matches the text
        cy.findByTestId('NativeAppSettings.AppDownloadLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Mattermost Apps Download Page Link:');

        // * Verify the Mattermost Apps Download Page Link input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('NativeAppSettings.AppDownloadLinkinput').should('have.value', origConfig.NativeAppSettings.AppDownloadLink);

        // * Verify the site name's help text is visible and matches the text
        cy.findByTestId('NativeAppSettings.AppDownloadLinkhelp-text').find('span').should('be.visible').and('have.text', 'Add a link to a download page for the Mattermost apps. When a link is present, an option to "Download Mattermost Apps" will be added in the Main Menu so users can find the download page. Leave this field blank to hide the option from the Main Menu.');

        // # Enter new App download link
        const newAppDownloadLink = 'https://example.com/app-download-link/';
        cy.findByTestId('NativeAppSettings.AppDownloadLinkinput').clear().type(newAppDownloadLink);

        // # Save setting
        saveSetting();

        // Get config again
        cy.apiGetConfig().then((response) => {
            const config = response.body;

            // * Verify the App download link is saved, directly via REST API
            expect(config.NativeAppSettings.AppDownloadLink).to.eq(newAppDownloadLink);
        });
    });

    it('SC20330 - Can change Help Link setting', () => {
        // * Verify that setting is visible and matches text content
        const contents = ['The URL for the Help link on the Mattermost login page, sign-up pages, and Main Menu. If this field is empty, the Help link is hidden from users.'];
        cy.findByTestId('SupportSettings.HelpLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Help Link:');

        // * Verify that help setting is visible and matches text content
        cy.findByTestId('SupportSettings.HelpLinkhelp-text').scrollIntoView().find('span').should('be.visible').and('have.text', contents[0]);

        // * Verify the input box visible and has default value
        cy.findByTestId('SupportSettings.HelpLinkinput').scrollIntoView().should('have.value', origConfig.SupportSettings.HelpLink).and('be.visible');

        // # Fill input field with value
        const stringToSave = 'https://some.com';
        cy.findByTestId('SupportSettings.HelpLinkinput').clear().type(stringToSave);

        // # Save setting
        saveSetting();

        // * Verify that the value is save, directly via REST API
        cy.apiGetConfig().then((response) => {
            expect(response.body.SupportSettings.HelpLink).to.equal(stringToSave);
        });
    });

    it('SC20341 Can change About Link setting', () => {
        const newAboutLink = 'https://about.mattermost.com/new-about-page/';

        // * Verify that setting is visible and has the correct label text
        cy.findByTestId('SupportSettings.AboutLinklabel').scrollIntoView().should('be.visible').and('have.text', 'About Link:');

        // * Verify that the help text is visible and matches text content
        cy.findByTestId('SupportSettings.AboutLinkhelp-text').should('be.visible').and('have.text', 'The URL for the About link on the Mattermost login and sign-up pages. If this field is empty, the About link is hidden from users.');

        // * Verify that the existing is visible and has default value
        cy.findByTestId('SupportSettings.AboutLinkinput').should('be.visible').and('have.value', origConfig.SupportSettings.AboutLink);

        // # Clear existing about link and type the new about link
        cy.findByTestId('SupportSettings.AboutLinkinput').clear().type(newAboutLink);

        // # Save setting
        saveSetting();

        cy.apiGetConfig().then((response) => {
            expect(response.body.SupportSettings.AboutLink).to.equal(newAboutLink);
        });
    });

    it('SC20329 - Can change Terms of Service Link setting', () => {
        // * Verify site name's setting name for is visible and matches the text
        cy.findByTestId('SupportSettings.TermsOfServiceLinklabel').scrollIntoView().should('be.visible').and('have.text', 'Terms of Service Link:');

        // * Verify the site name input box has default value. The default value depends on the setup before running the test.
        cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').should('have.value', origConfig.SupportSettings.TermsOfServiceLink);

        // * Verify the site name's help text is visible and matches the text
        cy.findByTestId('SupportSettings.TermsOfServiceLinkhelp-text').find('span').should('be.visible').and('have.text',
            'Link to the terms under which users may use your online service. By default, this includes the ' +
            '"Mattermost Conditions of Use (End Users)" explaining the terms under which Mattermost software is ' +
            'provided to end users. If you change the default link to add your own terms for using the service you ' +
            'provide, your new terms must include a link to the default terms so end users are aware of the Mattermost ' +
            'Conditions of Use (End User) for Mattermost software.');

        // # Enter a new help link
        const newValue = 'https://test.com';
        cy.findByTestId('SupportSettings.TermsOfServiceLinkinput').clear().type(newValue);

        // # Save setting
        saveSetting();

        // Get config again
        cy.apiGetConfig().then((response) => {
            const config = response.body;

            // * Verify the site name is saved, directly via REST API
            expect(config.SupportSettings.TermsOfServiceLink).to.eq(newValue);
        });
    });

    it('SC20339 - Can change Enable Custom Branding setting', () => {
        // # Make sure necessary field is false
        cy.apiUpdateConfig({TeamSettings: {EnableCustomBrand: false}});
        cy.reload();

        cy.findByTestId('TeamSettings.EnableCustomBrand').should('be.visible').within(() => {
            // * Verify that setting is visible and matches text content
            cy.get('label:first').should('be.visible').and('have.text', 'Enable Custom Branding: ');

            // * Verify that help setting is visible and matches text content
            const content = 'Enable custom branding to show an image of your choice, uploaded below, and some help text, written below, on the login page.';
            cy.get('.help-text').should('be.visible').and('have.text', content);

            // # Set Enable Custom Branding to true
            cy.findByTestId('TeamSettings.EnableCustomBrandtrue').check();
        });

        // # Save setting
        saveSetting();

        // * Verify that the value is save, directly via REST API
        cy.apiGetConfig().then((response) => {
            expect(response.body.TeamSettings.EnableCustomBrand).to.equal(true);
        });

        // # Set Enable Custom Branding to false
        cy.findByTestId('TeamSettings.EnableCustomBrandfalse').check();

        // # Save setting
        saveSetting();

        // * Verify that the value is save, directly via REST API
        cy.apiGetConfig().then((response) => {
            expect(response.body.TeamSettings.EnableCustomBrand).to.equal(false);
        });
    });
});

function saveSetting() {
    // # Click save button, and verify text and visibility
    cy.get('#saveSetting').
        should('have.text', 'Save').
        and('be.enabled').
        click().
        should('be.disabled').
        wait(TIMEOUTS.TINY);
}
